import {getToken,setToken,getUserInfomation,setUserInfomation,removeToken} from '@/utils/auth'
import {login,getUserInfo,logout} from '@/api/login'

const user = {
    state: {
        // token:null, // ←注意：一旦刷新页面，此处的“token”就会被赋值为初始值。初始值不能为空（因为当初始值是空值（即没有获取到token）时，在权限校验处，路由守卫（拦截器）会不让用户访问非登录页面）
        token:getToken(), // ←注意：一旦刷新页面，此处的“token”就会被赋值为初始值。在此处“getToken()”是初始值，它的作用就是解决刷新页面后“token”的初始值为“null”，从“localstorage”中获取“token”
        // user:null, // ←注意：一旦刷新页面，此处的“user”就会被赋值为初始值。初始值不能为空（因为当初始值是空值时，即使在浏览器的“本地存储空间”（即“localstorage”）中已有“user”的值的情况下，用户刷新页面后浏览器还是会通过“token”向后台发送请求获取用户信息）
        user:getUserInfomation(), // ←注意：一旦刷新页面，此处的“token”就会被赋值为初始值。在此处“getUserInfomation()”是初始值，它的作用就是解决刷新页面后“token”的初始值为“null”，从“localstorage”中获取“用户信息”
    },
    mutations: {
        // 下面的参数中的“state”代表旧的token，“token”代表新的token↓
        SET_TOKEN(state,token){
            state.token = token
            setToken(token)
        },
        // 下面的参数中的“state”代表旧的user，“user”代表新的user↓
        SET_USER(state,user){
            state.user = user
            setUserInfomation(user)
        }
    },
    actions: {
        // 在登录时获取token
        Login({commit},form){
            // “resolve”负责触发成功之后的处理（具体是向“@/views/login/index.vue”中的“this.$store.dispatch('Login',this.form)”处通知“已获取到并已在‘vuex’中保存好token”）↓
            // “reject”负责触发异常之后的处理（具体是向“@/views/login/index.vue”中的“this.$store.dispatch('Login',this.form)”处通知“出现了问题”）↓
            return new Promise((resolve,reject) => {
                 // “trim()”方法被用于删除字符串左右两边的空格↓
                login(form.username.trim(),form.password).then(response => {
                    const be_responsed_data = response.data // ←此处获取到的就是响应的data数据
                    commit('SET_TOKEN',be_responsed_data.data.token)
                    // 通知组件已经将token更新成功
                    resolve(be_responsed_data) // ←左边的括号里填入的是要向“@/views/login/index.vue”中的“this.$store.dispatch('Login',this.form)”处传入的数据
                }).catch(error => {
                    reject(error)
                })
            })
            
        },
        // 通过token获取用户信息
        // 注意：因为“state”是“被传入的值”，所以它需要被写在大括号的内部，否则浏览器的控制台会报错说“token”未被定义，找不到“token”↓
        GetUserInfo({commit,state}){
            console.log('GetUserInfo',state.token)
            return new Promise((resolve,reject) => {
                getUserInfo(state.token).then(response => {
                    const be_responsed_user_data = response.data
                    console.log('被返回的用户信息',be_responsed_user_data)
                    commit('SET_USER', be_responsed_user_data.data)
                    resolve(be_responsed_user_data)
                }).catch(error => {
                    reject(error)
                })
            })
            
        },
        // 退出系统
        Logout({commit,state}){
            return new Promise((resolve,reject) => {
                logout(state.token).then(response => {
                    const be_responsed_data = response.data
                    commit('SET_TOKEN',null) // ←注：左边这项也可以写为“commit('SET_TOKEN','')”
                    // commit('SET_USER',{}) // ←注：左边这项与“commit('SET_USER',null)”有区别（因为“{}”虽然是空对象，但它有值，它的值不为空（这句话的意思是虽然对象里的键没有键值，但是对象的骨架还是存在））
                    commit('SET_USER',null) // ←注：左边这项不能写作“commit('SET_USER',{})”（因为“{}”是空对象，但它有值，它的值不为空。如果使用它，会造成浏览器不能从后台接收用户信息（因为如上所述，空对象也是有值，所以会造成浏览器误认为本地有用户信息））
                    removeToken()
                    resolve(be_responsed_data)
                }).catch(error => {
                    reject(error)
                })
            })
        }
    }
}

export default user